﻿//Реализация главной формы приложения. Основная работа с интегрированным браузером
using System;
using System.IO;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Xml;

namespace LogViewer
{
    /// <summary>
    /// Главная форма
    /// </summary>
    internal partial class MainBrowserForm : Form
    {
        /// <summary>
        /// Рекурсивно ищет лог.файлы в текущей директории и выполняет инициализацию контролов
        /// </summary>
        public MainBrowserForm()
        {
            logFilesPaths = new List<string>(Directory.GetFiles(Directory.GetCurrentDirectory(), "*.fw.log", SearchOption.AllDirectories));
            resFolderPath = LogViewer.Properties.Settings.Default["logViewerResourceFolderPath"].ToString();

            logFilesPathToCombobox.DataSource = logFilesPaths;

            logFilesPaths.Sort(new Comparison<string>(this.Sort));

            
            InitializeComponent();
            comboBox1.FormattingEnabled = true;
            comboBox1.Format += new ListControlConvertEventHandler(ComboBox1Format);
            comboBox1.DataSource = logFilesPathToCombobox;

            this.loggersToolStripMenuItem.Enabled = false;
            this.rankToolStripMenuItem.Enabled = false;

            ShowHomePage();
        }


        /// <summary>
        /// Реализация красивого отображения имен лог.файлов в КомбоБоксе
        /// </summary>
        /// <param name="sender">msdn</param>
        /// <param name="e">msdn</param>
        private void ComboBox1Format(object sender, ListControlConvertEventArgs e)
        {
            string temp=(string) e.Value;
            temp = temp.Substring(temp.LastIndexOf('\\')+1);
            temp = temp.Replace('_', ':');
            temp = temp.Remove(temp.Length - 7, 7);
            e.Value = temp;
        }

        /// <summary>
        /// Изымает из текущего лог.файла имена всех зарегистрированных в нем логгеров
        /// </summary>
        /// <param name="xmlLogFile">путь до лог.файла</param>
        private void BuildRegisteredLoggersListFromFile(string xmlLogFile)
        {
            loggersToolStripMenuItem.DropDownItems.Clear();

            ToolStripMenuItem all_item = new ToolStripMenuItem("All");
            all_item.Click += new EventHandler(LoggerNameMenuItem_Click);
            loggersToolStripMenuItem.DropDownItems.Add(all_item);
            
            xmlDoc.Load(xmlLogFile);
            XmlNodeList nodes=xmlDoc.SelectNodes("logfile/registered_loggers/logger_name");
            foreach (XmlNode node in nodes)
            {
                ToolStripMenuItem temp=new ToolStripMenuItem(node.InnerText.Trim());
                temp.Click += new EventHandler(LoggerNameMenuItem_Click);
                loggersToolStripMenuItem.DropDownItems.Add(temp);
            }
        }


        /// <summary>
        /// Диалог открытия лог.файла
        /// </summary>
        /// <param name="sender">msdn</param>
        /// <param name="e">msdn</param>
        private void OpenOpenFileDialogButton_Click(object sender, EventArgs e)
        {
            DialogResult result=openFileDialog1.ShowDialog();
            if (result == DialogResult.OK)
            {
                if (!logFilesPaths.Contains(openFileDialog1.FileName))
                {
                    MessageBox.Show(openFileDialog1.FileName);
                    logFilesPaths.Add(openFileDialog1.FileName);
                    logFilesPaths.Sort(new Comparison<string>(this.Sort));
                    logFilesPathToCombobox.ResetBindings(true);
                }
            }

        }
        
        /// <summary>
        /// Функция сравнения файлов по времени создания
        /// </summary>
        /// <param name="file1">файл 1</param>
        /// <param name="file2">файл 2</param>
        /// <returns>1, если файл -1 старее, 1 - если наоборот, 0 - крайне редкий случай ;)</returns>
        private int Sort(string file1, string file2)
        {
            if (File.GetCreationTime(file1) > File.GetCreationTime(file2))
                return -1;
            if (File.GetCreationTime(file1) < File.GetCreationTime(file2))
                return 1;
            return 0;

        }

        /// <summary>
        /// Обработка клика в КомбоБоксе
        /// </summary>
        /// <param name="sender">msdn</param>
        /// <param name="e">msdn</param>
        private void ComboBox1SelectionChangeCommitted(object sender, EventArgs e)
        {
            FileInfo a = new FileInfo(logFilesPaths[comboBox1.SelectedIndex]);
            //отфильтруем пустые лог-файлы, который образуются при отладке
            //когда программист запустил каркас=>логгер создал лог фаил
            //а затем программист нажал Stop Debugging(Shift+F5)
            //такую ситуацию не отловить и созданный лог-файл останется пустым
            if (a.Length == 0)
            {
                ShowEmptyFilePage();
            }
            else
            {
                ShowHomePage();

                currentXmlLogFile = logFilesPaths[comboBox1.SelectedIndex];
                BuildRegisteredLoggersListFromFile(currentXmlLogFile);

                ShowMainHTMLPage();
                PushNewLogFileToBrowser(currentXmlLogFile);
                ((ToolStripMenuItem)this.rankToolStripMenuItem.DropDownItems[0]).Checked = false;
                this.rankToolStripMenuItem.DropDownItems[0].PerformClick();
                ((ToolStripMenuItem)this.loggersToolStripMenuItem.DropDownItems[0]).Checked = false;
                this.loggersToolStripMenuItem.DropDownItems[0].PerformClick();
            }
        }
        
        /// <summary>
        /// Открывает html-страничку поумолчанию (берет её из ресурсов)
        /// </summary>
        private void ShowHomePage()
        {
            OpenWebBrowserWithFile(resFolderPath+@"\HomePage.html");
            //OpenWebBrowserWithFile(@"D:\Documents and Settings\AV\Мои документы\_Projects\__CopInGame_Prototype\_Resource\Private\FrameWork\logger_res\HomePage.html");
            homePage = true;
        }

        /// <summary>
        /// Открывает пустую html-страничку (берет её из ресурсов)
        /// </summary>
        private void ShowEmptyFilePage()
        {
            OpenWebBrowserWithFile(resFolderPath+@"\EmptyFile.html");
            //OpenWebBrowserWithFile(@"D:\Documents and Settings\AV\Мои документы\_Projects\__CopInGame_Prototype\_Resource\Private\FrameWork\logger_res\EmptyFile.html");
        }

        /// <summary>
        /// Открывает основную html-страничку (берет её из ресурсов)
        /// </summary>
        private void ShowMainHTMLPage()
        {
            if (homePage)
            {
                OpenWebBrowserWithFile(resFolderPath+@"\MainHTML.html");
                //OpenWebBrowserWithFile(@"D:\Documents and Settings\AV\Мои документы\_Projects\__CopInGame_Prototype\_Resource\Private\FrameWork\logger_res\MainHtml.html");

                this.loggersToolStripMenuItem.Enabled = true;
                this.rankToolStripMenuItem.Enabled = true;
                homePage = false;
            }
        }

        #region Работа с браузерным визуальным компонентом
        /// <summary>
        /// Реализация работы с браузером (см. MSDN)
        /// </summary>
        /// <param name="file">путь до html-странички</param>
        private void OpenWebBrowserWithFile(string file)
        {
            webBrowser1.Navigate(file);
            if (webBrowser1.ReadyState == WebBrowserReadyState.Uninitialized) return;
            
            while (webBrowser1.ReadyState != WebBrowserReadyState.Complete)
            {
                Application.DoEvents();
            }
        }

        /// <summary>
        /// Передача браузеру нового xml-лог-файла для обработки через xslt и html-отображения
        /// </summary>
        /// <param name="filename">путь до лог.файла</param>
        private void PushNewLogFileToBrowser(string filename)
        {
            //webBrowser1.Navigate("javascript:setXmlLogFileName(\"" + filename.Replace("\\","\\\\") + "\");");
            webBrowser1.Document.InvokeScript("setXmlLogFileName", new object[] { filename });
            
        }

        /// <summary>
        /// Передача браузеру нового минимального приоритета сообщений для фильтрации отображаемых собщений
        /// </summary>
        /// <param name="rank">код приоритета</param>
        private void PushNewMessagePriorityToBrowser(string rank)
        {
            //webBrowser1.Navigate("javascript:setMessagePriority(\"" + rank + "\");");
            webBrowser1.Document.InvokeScript("setMessagePriority", new object[] { rank });
        }

        /// <summary>
        /// Передача браузеру нового имени логгера для фильтрации отображаемых собщений
        /// </summary>
        /// <param name="name">имя логгера</param>
        private void PushNewLoggerNameToBrowser(string name)
        {
            //webBrowser1.Navigate("javascript:setNameOfLogger(\"" + name + "\");");
            webBrowser1.Document.InvokeScript("setNameOfLogger", new object[] { name });
        }
        #endregion

        /// <summary>
        /// Обработка клика на меню приоритетов
        /// </summary>
        /// <param name="sender">msdn</param>
        /// <param name="e">msdn</param>
        private void MessagePriorityMenuItem_Click(object sender, EventArgs e)
        {
            StringBuilder query = PerformChecking((ToolStripMenuItem)sender);
         
            PushNewMessagePriorityToBrowser(query.ToString());
        }

        /// <summary>
        /// Обработка клика на меню логгеров
        /// </summary>
        /// <param name="sender">msdn</param>
        /// <param name="e">msdn</param>
        private void LoggerNameMenuItem_Click(object sender, EventArgs e)
        {
            StringBuilder query = PerformChecking((ToolStripMenuItem)sender);

            PushNewLoggerNameToBrowser(query.ToString());

        }

        /// <summary>
        /// Реализация умного меню (снимает галочки со всех пунктов, если пользователь снял галочку с пунтка "All")
        /// </summary>
        /// <param name="item">элемент меню</param>
        /// <returns>некоторый код для JavaScript и xlst</returns>
        private StringBuilder PerformChecking(ToolStripMenuItem item)
        {
            ToolStripMenuItem all_item = (ToolStripMenuItem)((ToolStripMenuItem)item.OwnerItem).DropDownItems[0];
            StringBuilder query = new StringBuilder();
            if (item.Text == "All")
            {
                all_item.Checked = !all_item.Checked;
                foreach (ToolStripMenuItem t in ((ToolStripMenuItem)item.OwnerItem).DropDownItems)
                    t.Checked = all_item.Checked;
                
            }
            else
            {
                all_item.Checked = false;
                item.Checked = !item.Checked;
            }


            foreach (ToolStripMenuItem t in ((ToolStripMenuItem)item.OwnerItem).DropDownItems)
                if (t.Checked==true)
                    query.Append(t.Text);
            return query;
        }

        /// <summary>
        /// Представление xml-лог файла в памяти
        /// </summary>
        private XmlDocument xmlDoc = new XmlDocument();
        /// <summary>
        /// пути до найденных лог.файлов
        /// </summary>
        private List<string> logFilesPaths;
        /// <summary>
        /// отображение имен. лог файлов в КомбоБоксе
        /// </summary>
        private BindingSource logFilesPathToCombobox = new BindingSource();
        /// <summary>
        /// Имя текущего просматриваемого лог.файла
        /// </summary>
        private string currentXmlLogFile;
        /// <summary>
        /// Путь до папки с ресурсами (html-странички поумолчанию и xslt-преобразования)
        /// </summary>
        private string resFolderPath;
        /// <summary>
        /// является ли открытая страничка "домашеней"
        /// </summary>
        private bool homePage = true;


    }

   
}